package com.zscat.mallplus.controller;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jpay.weixin.api.WxPayApi;
import com.zscat.mallplus.annotation.IgnoreAuth;
import com.zscat.mallplus.dms.entity.DmsOrder;
import com.zscat.mallplus.dms.service.*;
import com.zscat.mallplus.enums.OrderStatus;
import com.zscat.mallplus.enums.RoomStatus;
import com.zscat.mallplus.enums.TaskType;
import com.zscat.mallplus.qsg.*;
import com.zscat.mallplus.qsg.impl.MqttConfigService;
import com.zscat.mallplus.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import redis.clients.jedis.BinaryClient;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * 房间管理Controller
 */
@RestController
@Api(tags = "QsgRoomController", description = "房间管理")
@RequestMapping("/api/dms/room")
@Slf4j
public class QsgRoomController {

    @Autowired
    private IRoomService roomService;
    @Autowired
    private IDeviceService deviceService;
    @Autowired
    private IDeviceTaskService taskService;
    @Autowired
    private IDmsOrderService orderService;
    @Autowired
    private IQsgStoreService storeService;
    @Autowired
    private MqttConfigService mqttConfigService;
    @Autowired
    private IntegralService integralService;

    @IgnoreAuth
    @GetMapping(value = "/list")
    @ApiOperation(value = "房间列表")
    public Object list(Long storeId) {
        try {
            QueryWrapper qw = new QueryWrapper();
            qw.eq("store_id", storeId);
            List<QsgRoom> rooms = roomService.list(qw);
            if (null != rooms && rooms.size() > 0) {
                for (QsgRoom room : rooms) {
                    QsgDevice device = deviceService.getById(room.getDeviceId());
                    if (null != device) {
                        room.setDevice(device);
                    }
                }
            }
            return new CommonResult().success(rooms);
        } catch (Exception e) {
            e.printStackTrace();
            return new CommonResult().failed();
        }
    }




    /**
     * H5打扫完毕
     *
     * @param room
     * @return
     */
    @IgnoreAuth
    @PostMapping(value = "/update")
    @ApiOperation(value = "修改状态")
    public Object update(@RequestBody QsgRoom room) {
        try {
            //修改状态 断电 订单设置为已完成
            QsgRoom entity = roomService.getById(room.getId());
            entity.setStatus(room.getStatus());
            entity.setBeforeStatus(entity.getStatus());
            if (roomService.updateById(entity)) {
                QsgDevice device = deviceService.getById(entity.getDeviceId());
                QsgStore store = storeService.getById(device.getStoreId());
                //设备是离线状态
                Date expireTime = store.getSimOutTime();
                Date currentDate = new Date();
                if(1 == device.getOlStatus() || expireTime.before(currentDate)){
                    return new CommonResult().success("设备离线");
                }
                if (device.getDeviceType()==0){
                    QueryWrapper queryWrapper = new QueryWrapper();
                    queryWrapper.eq("device_code", device.getDeviceCode());
                    queryWrapper.eq("status", 0);
                    queryWrapper.eq("member_id", 1);
                    queryWrapper.eq("order_sn", "houtai");
                    List<QsgDeviceTask> tasks = taskService.list(queryWrapper);
                    if (null != tasks && tasks.size() > 0) {
                        for (QsgDeviceTask task : tasks) {
                            task.setStatus(1);
                            task.setUpdateTime(new Date());
                            task.setUpdateReason("后台点击打扫完毕更新");
                            taskService.updateById(task);
                        }
                    }
                    QsgDeviceTask task = new QsgDeviceTask();
                    task.setMemberId(1);
                    //关门任务
                    if (StringUtils.isNotBlank(device.getServerIp()) && StringUtils.isNotBlank(device.getServerPort())) {
                        task.setTaskType(TaskType.CLEAR_CLOSE.getValue());
                    } else {
                        task.setTaskType(TaskType.CLOSE_DOOR.getValue());
                    }
                    task.setDeviceId(device.getId());
                    task.setCreateDatetime(new Date());
                    task.setDeviceCode(device.getDeviceCode());
                    task.setEndTime(new Date());
                    task.setUpdateReason("后台点击关门生成");
                    task.setUpdateTime(new Date());
                    taskService.save(task);
                }else {
                    JSONObject data1 = new JSONObject();
                    JSONObject header1 = new JSONObject();
                    JSONObject body1 = new JSONObject();
                    header1.put("Code","1004");
                    header1.put("Time", System.currentTimeMillis());
                    header1.put("Sign","lvzaina");
                    data1.put("Header",header1);
                    body1.put("Delay",0);
                    body1.put("Cmd","Order");
                    body1.put("MsgId",1683557943);
                    body1.put("Lock",0);
                    body1.put("Type",0);
                    body1.put("ID",0);
                    JSONArray node = new JSONArray();
                    node.add(1);
                    node.add(2);
                    body1.put("Node",node);
                    data1.put("Body",body1);
                    mqttConfigService.publish("topic/receive/"+device.getDeviceCode(),data1.toJSONString());
                    QsgDeviceTask task = new QsgDeviceTask();
                    task.setStatus(1);
                    task.setDeviceCode(device.getDeviceCode());
                    task.setMemberId(1);
                    task.setTaskType(TaskType.GUANGZHOU_DASAO_COMPLETE.getValue());
                    task.setDeviceId(device.getId());
                    task.setEndTime(new Date());
                    task.setCreateDatetime(new Date());
                    task.setUpdateReason("广州设备后台点打扫完毕生成");
                    task.setUpdateTime(new Date());
                    taskService.save(task);
                }
            }
            return new CommonResult().success();
        } catch (Exception e) {
            e.printStackTrace();
            return new CommonResult().failed();
        }
    }

    @IgnoreAuth
    @PostMapping(value = "/clearOrder")
    @ApiOperation(value = "清空正在进行的订单")
    public Object clearOrder(@RequestBody QsgRoom room) {
        try {
            QsgRoom entity = roomService.getById(room.getId());
            QsgDevice device = deviceService.getById(entity.getDeviceId());
            if(device.getIsBilliard() == 0 && device.getIsDepositDevice() == 0){
                entity.setStatus(RoomStatus.ONLINE.getValue());
                entity.setBeforeStatus(room.getStatus());
            }else{
                entity.setStatus(RoomStatus.WAITCLEAN.getValue());
                entity.setBeforeStatus(entity.getStatus());
            }
            roomService.updateById(entity);
            QsgStore store = storeService.getById(device.getStoreId());
            //设备是离线状态
            Date expireTime = store.getSimOutTime();
            Date currentDate = new Date();
            if(1 == device.getOlStatus() || expireTime.before(currentDate)){
                return new CommonResult().success("设备离线");
            }
            //订单设置为已完成
            QueryWrapper qw = new QueryWrapper();
            qw.eq("store_id", device.getStoreId());
            qw.eq("order_status", OrderStatus.HAS_PAYMONEY.getValue());
            String now = DateUtil.dateToString(new Date(), "yyyy/MM/dd HH:mm:ss");
            qw.eq("device_id", device.getId());
            qw.le("start_time", now);
            List<DmsOrder> orders = orderService.list(qw);
            if (null != orders && orders.size() > 0) {
                for (DmsOrder order : orders) {
                    //分账
                    if (order.getIsSharing() == 1) {//0无需分账 1需要分账 2分账完成
                        try {
                            //待分账
                            Map<String, String> params = new TreeMap<>();
                            params.put("mch_id", store.getServerMchId());//服务商
                            params.put("appid", "wx697f0b89354ff12e");//服务商appid
                            params.put("sub_mch_id", store.getMchId());//出资方 根据订单的storeId获取
                            params.put("transaction_id", order.getWxOrderSn());//微信订单号 根据订单获取
                            params.put("nonce_str", System.currentTimeMillis() + "");
                            params.put("out_order_no", order.getOrderSn());
                            JSONObject jsonObject = new JSONObject();//分账的收款方信息
                            jsonObject.put("type", "MERCHANT_ID");
                            jsonObject.put("account", "1654635837");
                            jsonObject.put("amount", order.getPrice().multiply(new BigDecimal(100).multiply(new BigDecimal(store.getScale()))).setScale(0, BigDecimal.ROUND_DOWN));
                            jsonObject.put("description", store.getName() + "_" + order.getOrderSn());//店铺名+订单号
                            JSONArray jsonArray = new JSONArray();
                            jsonArray.add(jsonObject);
                            params.put("receivers", jsonArray.toJSONString());
                            String sign = WechatUtil.arrayHmacsha(params, "a0a4e42ee0f0ef84b71294c7235ca1e2");
                            params.put("sign", sign);
                            //上线后需改为线上模式
                            String i = WxPayApi.profitsharing(params, store.getServerCertPath(), store.getServerMchId());//参数 证书地址 服务商证书密码默认即商户号
                            Map<String, Object> resultUn = XmlUtil.xmlStrToMap(i);
                            String return_code = MapUtils.getString("return_code", resultUn);
                            String result_code = MapUtils.getString("result_code", resultUn);
                            if (result_code.equalsIgnoreCase("SUCCESS") && return_code.equalsIgnoreCase("SUCCESS")) {
                                order.setIsSharing(2);
                                orderService.updateById(order);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    order.setOrderStatus(OrderStatus.COMPLETED.getValue());
                    //如果是台球后付费设备并且是积分支付需要扣费
                    if(device.getIsBilliard() == 0 && device.getIsDepositDevice() == 0 && 1 == order.getPayMethod().intValue()){
                        BigDecimal payMoney = orderService.calPayMoney(order);
                        QueryWrapper qwone = new QueryWrapper();
                        qwone.eq("member_id",order.getMemberId());
                        qwone.eq("store_id",order.getStoreId());
                        QsgIntegral integral = integralService.getOne(qwone);
                        int payIntegral = payMoney.multiply(new BigDecimal(100)).intValue();
                        int refundIntegral = integral.getIntegral() - payIntegral;
                        if(refundIntegral < 0){
                            refundIntegral = 0;
                        }
                        integral.setIntegral(refundIntegral);
                        integralService.updateById(integral);

                        Date currentTime = new Date();
                        order.setActEndTime(currentTime);
                        order.setEndTime(DateUtil.dateToString(currentTime,"yyyy/MM/dd HH:mm"));
                        order.setPrice(payMoney);
                        order.setIntegral(payIntegral);
                    }
                    orderService.updateById(order);
                    //把这笔订单的任务设置为1
                    if (device.getDeviceType()==0){
                        QueryWrapper queryWrapper = new QueryWrapper();
                        queryWrapper.eq("order_sn", order.getOrderSn());
                        List<QsgDeviceTask> taskTypes = taskService.list(queryWrapper);
                        if (null != taskTypes && taskTypes.size() > 0) {
                            for (QsgDeviceTask taskType : taskTypes) {
                                taskType.setStatus(1);
                                taskType.setUpdateTime(new Date());
                                taskType.setUpdateReason("后台点击清除订单时修改");
                                taskService.updateById(taskType);
                            }
                        }
                    }else if(device.getIsGateway() == 0){
                        QueryWrapper queryWrapper = new QueryWrapper();
                        queryWrapper.eq("order_sn", order.getOrderSn());
                        List<QsgDeviceTask> taskTypes = taskService.list(queryWrapper);
                        if (null != taskTypes && taskTypes.size() > 0) {
                            for (QsgDeviceTask taskType : taskTypes) {
                                taskType.setStatus(1);
                                taskType.setUpdateTime(new Date());
                                taskType.setUpdateReason("网关设备点击清除订单时修改");
                                taskService.updateById(taskType);
                            }
                        }
                    }else {
                        JSONObject data1 = new JSONObject();
                        JSONObject header1 = new JSONObject();
                        JSONObject body1 = new JSONObject();
                        header1.put("Code","1004");
                        header1.put("Time", new Date().getTime());
                        header1.put("Sign","lvzaina");
                        data1.put("Header",header1);
                        body1.put("Delay",0);
                        body1.put("Cmd","Order");
                        body1.put("MsgId",1683557943);
                        body1.put("Lock",0);
                        body1.put("Type",0);
                        body1.put("ID",0);
                        JSONArray node = new JSONArray();
                        node.add(1);
                        node.add(2);
                        body1.put("Node",node);
                        data1.put("Body",body1);
                        mqttConfigService.publish("topic/receive/"+device.getDeviceCode(),data1.toJSONString());
                    }
                }
            }
            return new CommonResult().success();
        } catch (Exception e) {
            e.printStackTrace();
            return new CommonResult().failed();
        }
    }


    /**
     * 修改房间状态
     *
     * @param room 房间信息
     * @return
     */
    @IgnoreAuth
    @PostMapping(value = "/updateRoomStatus")
    @ApiOperation(value = "修改房间状态")
    public Object updateRoomStatus(@RequestBody QsgRoom room) {
        try {
            QsgRoom entity = roomService.getById(room.getId());
            entity.setStatus(room.getStatus());
            if (roomService.updateById(entity)) {
                return new CommonResult().success();
            }
            return new CommonResult().failed();
        } catch (Exception e) {
            log.error("修改房间状态失败.异常:{}",e.getMessage());
            return new CommonResult().failed();
        }
    }


    /**
     * 查询房间状态
     *
     * @param deviceId 设备编号
     * @return
     */
    @IgnoreAuth
    @GetMapping(value = "/getRoomStatus")
    @ApiOperation(value = "根据设备查询房间的状态")
    public Object getRoomStatus(@RequestParam Long deviceId) {
        try {
            QueryWrapper qw = new QueryWrapper();
            qw.eq("device_id",deviceId);
            QsgRoom entity = roomService.getOne(qw);
            return new CommonResult().success(entity);
        } catch (Exception e) {
            log.error("修改房间状态失败.异常:{}",e.getMessage());
            return new CommonResult().failed();
        }
    }
}
